package rensoft.portfolio.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class CrawlerFilter implements Filter {

  private static final String _ESCAPED_FRAGMENT = "_escaped_fragment_=";

  public void destroy() {}

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    if (isCrawlerRequest(httpRequest.getQueryString()))
      returnCrawlableResponse(response, httpRequest);
    else chain.doFilter(request, response);
  }

  public void init(FilterConfig filterConfig) throws ServletException {}

  private String createSnapshotFilePath(HttpServletRequest request) {
    String fileName = "SNAPSHOT";
    String queryString = request.getQueryString();
    if (queryString != null) {
      queryString = queryString.replace(_ESCAPED_FRAGMENT, "");
      if (!queryString.isEmpty()) fileName += queryString.replace("=", "EQUALS");
    }
    return "crawler_snapshots/" + fileName + ".html";
  }

  private boolean isCrawlerRequest(String query) {
    return query != null && query.contains(_ESCAPED_FRAGMENT);
  }

  private void returnCrawlableResponse(ServletResponse response, HttpServletRequest request)
      throws IOException, MalformedURLException, UnsupportedEncodingException {
    response.setContentType("text/html");
    response.setCharacterEncoding("ISO-8859-1");
    ServletOutputStream out = response.getOutputStream();
    File file = new File(createSnapshotFilePath(request));
    byte[] buffer = new byte[(int) file.length()];
    FileInputStream fileInput = new FileInputStream(file);
    fileInput.read(buffer);
    fileInput.close();
    out.write(buffer);
    out.close();
  }
}
